﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using CascadeDropDown.Component;
using System.Reflection;
using CascadeDropDown.Library.Component;
using System.Web.UI.WebControls;

namespace CascadeDropDown.Helpers
{
    public class DataBindHelper
    {
        public static void Bind(Control mainControl, object data, params string[] exceptColumns)
        {
            Type dataType = data.GetType();
            var properties = dataType.GetProperties();
            foreach (Control ctrl in mainControl.Controls)
            {
                if (ctrl is IMyControl)
                {
                    IMyControl myControl = (ctrl as IMyControl);
                    if (string.IsNullOrEmpty(myControl.BindColumnName)) continue;

                    PropertyInfo propInfo = properties.
                            Where(pi => pi.Name == myControl.BindColumnName).
                                    First();

                    object dataValue = propInfo.GetValue(data, null);

                    if (dataValue != null)
                    {
                        myControl.setValue(dataValue);
                    }
                    if (propInfo.GetSetMethod() == null)
                    {
                        myControl.ControlEnabled = false;
                    }

                }
                if (ctrl.Controls.Count > 0)
                {
                    Bind(ctrl, data);
                }
            }
        }
        public static T GetModel<T>(Control mainControl) where T : new()
        {
            return GetModelPriv(mainControl, new T());

        }
        private static T GetModelPriv<T>(Control mainControl, T model) where T : new()
        {
            Type dataType = model.GetType();
            var properties = dataType.GetProperties();
            foreach (Control ctrl in mainControl.Controls)
            {
                if (ctrl is IMyControl)
                {
                    IMyControl myControl = (ctrl as IMyControl);

                    if (myControl.getValue() != null && !string.IsNullOrEmpty(myControl.BindColumnName))
                    {
                        var propInfo = properties.
                                Where(pi => pi.Name == myControl.BindColumnName).
                                        First();
                        Type propType = Nullable.GetUnderlyingType(propInfo.PropertyType) ?? propInfo.PropertyType;
                        if (propInfo.GetSetMethod() != null && !String.IsNullOrEmpty(myControl.getValue().ToString()))
                        {
                            propInfo.SetValue(model, Convert.ChangeType(myControl.getValue(), propType), null);
                        }
                    }
                }
                if (ctrl.Controls.Count > 0)
                {
                    GetModelPriv(ctrl, model);
                }
            }
            return model;
        }

        public static void ClearForm(Control mainControl, params string[] exceptControlIDList)
        {
            foreach (Control ctrl in mainControl.Controls)
            {
                if (ctrl is IMyControl && !exceptControlIDList.Contains(ctrl.ID))
                {
                    IMyControl myControl = (ctrl as IMyControl);
                    myControl.setValue(string.Empty);
                }
                if (ctrl.Controls.Count > 0)
                {
                    ClearForm(ctrl, exceptControlIDList);
                }
            }
        }

        public static void ConfigureView<TViewModel>(Control mainControl, ViewModelBase<TViewModel> viewModel) where TViewModel : ViewModelBase<TViewModel>, new()
        {
            Type dataType = viewModel.GetType();
            var properties = dataType.GetProperties();
            foreach (Control ctrl in mainControl.Controls)
            {
                if (ctrl is IMyControl)
                {
                    IMyControl myControl = (ctrl as IMyControl);
                    if (string.IsNullOrEmpty(myControl.BindColumnName)) continue;

                    PropertyInfo propInfo = properties.
                            Where(pi => pi.Name == myControl.BindColumnName).
                                    First();

                    object dataValue = propInfo.GetValue(viewModel, null);

                    //if (dataValue != null)
                    //{
                    myControl.setValue(dataValue);
                    //}

                    myControl.Visible = viewModel.CanGet(myControl.BindColumnName);
                    myControl.ControlEnabled = propInfo.GetSetMethod() != null && viewModel.CanSet(myControl.BindColumnName);

                    if (myControl is DataBoundControl && viewModel.HasDataSourceFor(myControl.BindColumnName) && myControl.ControlEnabled)
                    {
                        //ctrl.EnableViewState = false;
                        (myControl as DataBoundControl).DataSource = viewModel.GetDatasourceFor(myControl.BindColumnName);
                        (myControl as DropDownList).AutoPostBack = true;
                        (myControl as DataBoundControl).DataBind();
                    }
                }
                if (ctrl.Controls.Count > 0)
                {
                    ConfigureView(ctrl, viewModel);
                }
            }

        }
    }
}
